package cn.fanyamin.dao.ibatis;

import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.orm.ibatis.SqlMapClientCallback;

import cn.fanyamin.business.NoResultsFoundException;
import cn.fanyamin.dao.TaskDao;
import cn.fanyamin.domain.Context;
import cn.fanyamin.domain.Goal;
import cn.fanyamin.domain.Remind;
import cn.fanyamin.domain.RemindTask;
import cn.fanyamin.domain.RepeatInfo;
import cn.fanyamin.domain.Task;
import cn.fanyamin.util.collection.CollectionUtils;

import com.ibatis.sqlmap.client.SqlMapExecutor;



public class SqlMapTaskDao extends CRUDDao<Integer,Task> implements TaskDao {
	protected String domainName = "Task";
	
	public SqlMapTaskDao() {
		setSQLID(domainName);
	}

    public List<Task> getTaskList(int taskType, int userID) {
        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("taskType", taskType);
        map.put("userID", userID);
        
        List<Task> list = (List<Task>) getSqlMapClientTemplate().queryForList("getTaskList", map);
        if (null == list) {
            throw new NoResultsFoundException("getTaskList" + ", userID=" + userID + ", taskType=" + taskType);
        }

        return list;
    }

    public List<Task> list(int userID) {
        List<Task> list = (List<Task>) getSqlMapClientTemplate().queryForList("getListOfTask", userID);
        if (null == list) {
            throw new NoResultsFoundException("getListOfTask userID=" + userID);
        }

        return list;
    }

    public Map<Integer, Context> getContexts() {
        Map<Integer, Context> ret = (Map<Integer, Context>) getSqlMapClientTemplate().queryForMap("getContexts", null, "contextID");

        if (null == ret) {
            throw new NoResultsFoundException("getContexts");
        }

        return ret;
    }
    
	public int createGoal(Goal t) {
		Integer ret = (Integer) getSqlMapClientTemplate().insert("createGoal", t);

		return ret;
	}


	public List<Goal> getGoalList(int goalType, int userID) {
		Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("goalType", goalType);
        map.put("userID", userID);
        
		List<Goal> list = (List<Goal>) getSqlMapClientTemplate().queryForList(
				"getGoalList", map);
		if (null == list) {
			throw new NoResultsFoundException("getGoalList");
		}

		return list;
	}


	public int deleteGoal(int goalID) {
		return getSqlMapClientTemplate().delete("deleteGoal", goalID);
	}

	public Goal retrieveGoal(int goalID) {
		Goal ret = (Goal) getSqlMapClientTemplate().queryForObject(
				"retrieveGoal", goalID);

		if (null == ret) {
			throw new NoResultsFoundException("retrieveGoal" + ", id=" + goalID);
		}

		return ret;
	}

	public int updateGoal(Goal goal) {
		return getSqlMapClientTemplate().update("updateGoal", goal);
	}

	public List<Goal> findGoal(Goal goal, String[] fields) {
		Map<String, Object> map = new HashMap<String, Object>();
        
        map.put("userID", goal.getUserID());
        for(String strField: fields) {
        	try {
				map.put(strField, goal.getField(strField));
			} catch (Exception e) {
				throw new RuntimeException("error of goal.getFiled " + strField );
			}
        }
		List<Goal> list = (List<Goal>) getSqlMapClientTemplate().queryForList(
				"findGoal", map);
		if (null == list) {
			throw new NoResultsFoundException("getGoalList");
		}

		return list;
	}

	public List<Task> findTasks(Task task) {
		List<String> fields = new ArrayList<String>(4);
		if (task.getContextID() > 0) {
			fields.add("contextID");
		}
		if (task.getCategoryID() > 0) {
			fields.add("categoryID");
		}
		if (task.getDuration() > 0) {
			fields.add("duration");
		}
		if (task.getPriority() > 0) {
			fields.add("priority");
		}
		if (task.getEnergy() > 0) {
			fields.add("energy");
		}
		if (StringUtils.isNotBlank(task.getTaskName())) {
			fields.add("taskName");
		}
		
		Map<String, Object> map = new HashMap<String, Object>();
        
        map.put("userID", task.getUserID());
        for(String strField: fields) {
        	try {
				map.put(strField, task.getField(strField));
			}catch (Exception e) {
				throw new RuntimeException("Error of task.getField" + strField);
			}
        	logger.debug(strField + "===" + map.get(strField));
        }
        
		List<Task> list = (List<Task>) getSqlMapClientTemplate().queryForList(
				"findTask", map);
		if (null == list) {
			throw new NoResultsFoundException("findTask");
		}

		return list;
	}

	public List<Goal> getAllGoalList(int userID) {
		List<Goal> list = (List<Goal>) getSqlMapClientTemplate().queryForList(
				"getAllGoalList", userID);
		if (null == list) {
			throw new NoResultsFoundException("getAllGoalList");
		}

		return list;
	}

	public List<Task> getTaskList(Date fromDate, Date toDate, int userID) {
		Map<String, Object> map = new HashMap<String, Object>();
        map.put("fromDate", fromDate);
        map.put("toDate", toDate);
        map.put("userID", userID);
		
		List<Task> list = (List<Task>) getSqlMapClientTemplate().queryForList(
				"getTaskListAsDate", map);
		if (null == list) {
			throw new NoResultsFoundException("getTaskListAsDate");
		}

		return list;
	}

	public List<Task> getTaskListByDeadline(Date fromDate, Date toDate, int userID) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("fromDate", fromDate);
        map.put("toDate", toDate);
        map.put("userID", userID);
        
        List<Task> list = (List<Task>) getSqlMapClientTemplate().queryForList(
                "getTaskListByDeadline", map);
        if (null == list) {
            throw new NoResultsFoundException("getTaskListByDeadline");
        }

        return list;
    }
	
	public List<Task> getFinishedTasks(int userID) {
		 List<Task> list = (List<Task>) getSqlMapClientTemplate().queryForList("getFinishedTasks", userID);
	        if (null == list) {
	            throw new NoResultsFoundException("getFinishedTasks" + ", userID=" + userID);
	        }

	        return list;
	}

	public int finishTask(int taskID) {
		Task task = new Task();
		task.setTaskID(taskID);
		task.setEndTime(new Timestamp(System.currentTimeMillis()));
		return getSqlMapClientTemplate().update("finishTask", task);
	}

    public int cleanFinishedRemindTask(int count) {        
        return getSqlMapClientTemplate().delete("cleanFinishedRemindTask", count);
    }

    public int cleanFinishedTask(int count) {        
        return getSqlMapClientTemplate().delete("cleanFinishedTask", count);
    }

    public int cleanFinishedEmailTask(int count) {        
        return getSqlMapClientTemplate().delete("cleanFinishedEmailTask", count);
    }

    //---------remind
    public int createRemind(Remind rm) {
        return (Integer)getSqlMapClientTemplate().insert("createRemind", rm);
    }


    public int updateRemind(Remind rm, int status) {
        Map<String, Object> paraMap = new HashMap<String, Object>();
        paraMap.put("status", rm.getStatus());
        paraMap.put("remindID", rm.getRemindID());
        paraMap.put("remindTime", rm.getRemindTime());
        paraMap.put("remindMethod", rm.getRemindMethod());
        paraMap.put("newStatus", status);
        
        return getSqlMapClientTemplate().update("updateRemind",paraMap);
    }

    public List<RemindTask> getRemindTaskList() {
        List<RemindTask> ret = (List<RemindTask>) getSqlMapClientTemplate().queryForList("listRemindTask");

        if (CollectionUtils.isEmpty(ret)) {
            throw new NoResultsFoundException("listRemindTask");
        }

        return ret;
    }

    public Remind retrieveRemind(int remindID) {
        Remind ret = (Remind) getSqlMapClientTemplate().queryForObject("retrieveRemind", remindID);

        if (null == ret) {
            throw new NoResultsFoundException("retrieveRemind" + ", id=" + remindID);
        }

        return ret;
    }

    public void finishRemindTask(final List<RemindTask> taskList) {
        SqlMapClientCallback callback = new SqlMapClientCallback() {
            public Object doInSqlMapClient(SqlMapExecutor executor)
                    throws SQLException {
                executor.startBatch();
                for (RemindTask task : taskList) {
                    executor.update("updateRemindTask", task);
                }
                executor.executeBatch();
                return null;
            }
        };
        this.getSqlMapClientTemplate().execute(callback);
    }
    
    public int deleteRemind(int remindID) {
        return getSqlMapClientTemplate().delete("deleteRemind", remindID);
    }
    //--repeat
    public int createRepeatInfo(RepeatInfo ri) {
        Integer ret = (Integer) getSqlMapClientTemplate().insert("createRepeatInfo", ri);
        return ret;
    }

    public List<Task> getRepeatTaskList() {
        List<Task> list = (List<Task>) getSqlMapClientTemplate().queryForList("getRepeatTasks", null);
        if (null == list) {
            throw new NoResultsFoundException("getRepeatTasks");
        }

        return list;
    }

	public RepeatInfo retrieveRepeatInfo(int repeatID) {
		RepeatInfo ret = (RepeatInfo) getSqlMapClientTemplate().queryForObject(
				"retrieveRepeatInfo", repeatID);

		if (null == ret) {
			throw new NoResultsFoundException("retrieveRepeatInfo" + ", id=" + repeatID);
		}

		return ret;
	}

    public int deleteRepeatInfo(int repeatID) {
        return getSqlMapClientTemplate().delete("deleteRepeatInfo", repeatID);
    }

    public int updateRepeatInfo(RepeatInfo ri) {
        return getSqlMapClientTemplate().update("updateRepeatInfo", ri);
    }

	public List<Task> getSubTaskList(int taskID) {
		List<Task> list = (List<Task>) getSqlMapClientTemplate().queryForList("getSubTaskList", taskID);
        if (null == list) {
            return new ArrayList<Task>();
        }

        return list;
	}

	public int getSubTaskCount(int taskID) {
		return (Integer) getSqlMapClientTemplate().queryForObject(
				"getSubTaskCount", taskID);
	}

   


}
